package glassline;

import glassline.Glass.GlassShape;
import glassline.Glass.WorkStation;
import glassline.interfaces.Robot;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import transducer.TChannel;
import transducer.TEvent;

public class RobotAgent extends FactoryAgent implements Robot {
	public List<Glass> glassQueue = Collections.synchronizedList(new ArrayList<Glass>());
	static int glassCount = 1;
	
	public boolean transportingGlass = false;
	
	public RobotAgent() {
		super(0);
	}
	
	// Messages

	/* (non-Javadoc)
	 * @see glassline.Robot#msgHereIsGlass(glassline.Glass)
	 */
	public void msgHereIsGlass(Glass g) {} // Not needed.

	/* (non-Javadoc)
	 * @see glassline.Robot#msgGetGlassFromBin()
	 */
	public void msgGetGlassFromBin(GlassShape shape, ArrayList<WorkStation> stations) {
		//print("Received order to move glass to the conveyor.");
		
		glassQueue.add(new Glass(shape, stations, glassCount++));
		updateControlPanelQueueSize();
		
		stateChanged();
	}
	
	public void msgReceivedGlass() {
		//print("Conveyor received glass");
		
		transportingGlass = false;
		stateChanged();
	}
	
	// Scheduler

	/* (non-Javadoc)
	 * @see glassline.Cutter#pickAndExecuteAnAction()
	 */
	@Override
	public boolean pickAndExecuteAnAction() {
		// Rule #1
		if (!glassQueue.isEmpty() && !transportingGlass && nextSpaceAvailable()) {
			createGlass();
			return true;
		}
		return false;
	}

	// Actions
	
	private void createGlass() {
		Factory.transducer.fireEvent(TChannel.BIN, TEvent.BIN_CREATE_PART, null);
		transportingGlass = true;
		nextComponent.component.msgHereIsGlass(glassQueue.get(0));
		glassQueue.remove(0);
		updateControlPanelQueueSize();
	}
	
	// Utilities
	
	private void updateControlPanelQueueSize() {
		// Tell the control panel to update the queue.
		Object[] args = {glassQueue.size()};
		Factory.transducer.fireEvent(TChannel.CONTROL_PANEL, TEvent.GLASS_QUEUE_UPDATED, args);
	}
}
